package token

import (
	"fmt"
	jwt "github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"time"
)

type TokenContext struct {
	Uid         uint64
	PhoneNumber string
	Role        uint64
}

// 生成token
func Sign(c TokenContext, secret string) (tokenString string, err error) {
	//根据配置信息获取
	if secret == "" {
		secret = viper.GetString("jwt_secret")
	}
	//生成token内容
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"uid":         c.Uid,
		"phonenumber": c.PhoneNumber,
		"role":        c.Role,
		"exp":         time.Now().Add(time.Hour * 24 * 7).Unix(), //过期时间七天
	})
	//生成token
	tokenString, err = token.SignedString([]byte(secret))
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

// 验证token
func ValidateToken(c *gin.Context) (*TokenContext, error) {
	//获取客户端传递的token 客户端将token放在http头部字段 --Token 发起请求
	//服务端获取http头部字段token保存
	tokenstring := c.Request.Header.Get("Token")
	ctx := &TokenContext{}
	if tokenstring == "" {
		return ctx, fmt.Errorf("token为空")
	}
	//解析token
	token, err := jwt.Parse(tokenstring, secretFunc)
	if err != nil {
		return ctx, err
	} else if claims, ok := token.Claims.(jwt.MapClaims); ok {
		ctx.Uid = uint64(claims["uid"].(float64))
		ctx.PhoneNumber = claims["phonenumber"].(string)
		ctx.Role = uint64(claims["role"].(float64))
		return ctx, nil
	} else {
		print(ctx)
		return ctx, fmt.Errorf("无法解析!")
	}

}

func secretFunc(token *jwt.Token) (interface{}, error) {
	return []byte(viper.GetString("jwt_secret")), nil
}
